﻿using System;
using System.Linq;
using System.Collections.Generic;
using PharmacyPharnet.Core;
using Pharmacy.ExceptionHandling;
using System.Windows.Forms;
using DevExpress.XtraGrid;
using Pharmacy.Data.Repositories;
using Pharmacy.Data;
using Pharmacy.Ultilities;
using Pharmacy.Data.Entity;
using Pharmacy.Business.Generator;
using PharmacyPharnet.MasterData;
using DevExpress.XtraEditors;
using Pharmacy.Business;
using Pharmacy.Ultilities.Resources;
using Pharmacy.Data.Core;



namespace PharmacyPharnet.KinhDoanh
{
    public partial class FrmBangBaoGiaChiTiet : FrmEditBase
    {
        #region Declarations
        IObjectContext pharmacyContext;
        PhieuBaoGiaBO pbgBO;
        PhieuBaoGia currentPhieuBaoGia;
        PhieuBaoGia originalPhieuBaoGia;
        MasterItemRepository rMasterItem;
        /// <summary>
        /// Keep track all PhieuBaoGiaChiTiets are temporarily deleted in form.
        /// </summary>
        List<PhieuBaoGiaChiTiet> lstPhieuBaoGiaChiTietDeleted;
        bool applyAllVAT = false;
        bool applyAllDiscount = false;
        #endregion

        #region Constructors
        public FrmBangBaoGiaChiTiet()
        {
            InitializeComponent();
        }

        public FrmBangBaoGiaChiTiet(Enums.ActionForm actionForm)
            : this()
        {
            CurrentAction = actionForm;            
        }

        public FrmBangBaoGiaChiTiet(IObjectContext objectContext, PhieuBaoGia objPhieuBaoGia, Enums.ActionForm actionForm)
            : this(actionForm)
        {
            pharmacyContext = objectContext;
            currentPhieuBaoGia = objPhieuBaoGia;
            originalPhieuBaoGia = objPhieuBaoGia;
        }
        #endregion

        #region Override Methods
        protected override void InitializeBO()
        {
            if (pharmacyContext == null)
                pharmacyContext = ObjectContextFactory.CreatePharmacyContext(Global.UserName, Global.CurrentConnectionString);
            if (pbgBO == null)
                pbgBO = new PhieuBaoGiaBO(pharmacyContext);
        }

        protected override void PopulateStaticData()
        {
            luePBGdetailItem.DataSource = LoadItemList(0);
            LoadMasterLocationList(0);
            LoadVendorList(0);
            lstPhieuBaoGiaChiTietDeleted = new List<PhieuBaoGiaChiTiet>();
        }

        protected override void PopulateData()
        {
            if (CurrentAction == Enums.ActionForm.None)
                CurrentAction = Enums.ActionForm.New;
            BindDataToControl();
        }
        #endregion

        #region Custom Methods
        private void RegisterEventHandlers()
        {
            btnCancel.Click += btnCancel_Click;
            btnClose.Click += btnClose_Click;
            btnDelete.Click += btnDelete_Click;
            btnNew.Click += btnNew_Click;
            btnSave.Click += btnSave_Click;
        }

        /// <summary>
        /// Thiết lập 1 số giá trị default cho form khi tạo mới phiếu báo giá như : 
        /// Mã Số Phiếu; Ngày lập
        /// </summary>
        private void SetDefaultValue()
        {
            DateTime currentdate = pharmacyContext.GetCurrentDateTime();
            txtPBGNumber.Text = IdentityGeneratorHelper.GetNextNumber(Enums.GeneratorObjectType.PhieuBaoGiaGenerator, currentdate, null, pharmacyContext);
            dtePBGDocumentDate.EditValue = currentdate;
            dtePBGDocumentDate.Focus();
        }

        /// <summary>
        /// Enable / Disable các control trong form. 
        /// Nếu CurrentAction = New/Edit : cho phép chỉnh sửa thông tin; ngược lại disable các control
        /// </summary>
        private void EnableControlToEdit()
        {
            bool enable = true;
            if (CurrentAction == Enums.ActionForm.View)
            {
                enable = false;
            }
            dtePBGDocumentDate.Properties.ReadOnly = !enable;
            txtPBGNote.Properties.ReadOnly = !enable;
            txtPBGTienCK.Properties.ReadOnly = !enable;
            txtPBGTienVAT.Properties.ReadOnly = !enable;
            luePBGMasterLocation.Properties.ReadOnly = !enable;
            luePBGVendor.Properties.ReadOnly = !enable;
            grvPBGDetail.OptionsBehavior.Editable = enable;
        }

        /// <summary>
        /// Load danh sách sản phẩm trong hệ thống
        /// </summary>
        private List<MasterItem> LoadItemList(int selectedID)
        {
            rMasterItem = new MasterItemRepository(pharmacyContext, MergeOption.Overrive);
            return rMasterItem.AsQueryable().ToList();
        }

        /// <summary>
        /// Load danh sách nhà cung cấp trong hệ thống
        /// </summary>
        private void LoadVendorList(int selectedID)
        {
            VendorRepository rVendor = new VendorRepository(pharmacyContext, MergeOption.Overrive);
            luePBGVendor.Properties.DataSource = rVendor.AsQueryable().ToList();
            luePBGVendor.EditValue = selectedID;

        }

        /// <summary>
        /// Load danh sách nơi được báo giá (Location) trong hệ thống
        /// </summary>
        private void LoadMasterLocationList(int selectedID)
        {
            MasterLocationRepository rMasterLocation = new MasterLocationRepository(pharmacyContext, MergeOption.Overrive);
            luePBGMasterLocation.Properties.DataSource = rMasterLocation.AsQueryable().ToList();
            luePBGMasterLocation.EditValue = selectedID;

        }

        /// <summary>
        /// Hiển thị thông tin chi tiết của Nhà Cung Cấp, Nơi Báo Giá
        /// </summary>
        private void DisplayInformationOfObject(object viewObject)
        {
            if (viewObject.ToString() == typeof(Vendor).FullName)
            {
                Vendor v = viewObject as Vendor;
                ShippingInfo sh = v.ShippingInfo;
                ContactInfo contact = v.ContactInfo;
                mmeInformationDetail.Text = string.Format("Nhà cung cấp: {0} | Số ĐT: {1} | Fax : {2} \r\n Liên hệ : {3} | Số ĐT : {4} | Cell : {5}",
                    v.FullName, sh != null ? sh.Phone: string.Empty, sh != null ? sh.Fax: string.Empty, 
                    contact != null? contact.Name : string.Empty, contact != null? contact.Phone : string.Empty, contact != null? contact.MobilePhone: string.Empty);
            }
            else if (viewObject.ToString() == typeof(MasterLocation).FullName)
            {
                MasterLocation m = viewObject as MasterLocation;
                ShippingInfo sh = m.ShippingInfo;
                ContactInfo contact = m.ContactInfo;
                mmeInformationDetail.Text = string.Format("Nơi được báo giá: {0} | Số ĐT: {1} | Fax : {2} \r\n Liên hệ : {3} | Số ĐT : {4} | Cell : {5}",
                                                            m.Name, sh != null ? sh.Phone : string.Empty, sh != null ? sh.Fax : string.Empty,
                                                            contact != null ? contact.Name : string.Empty, contact != null ? contact.Phone : string.Empty, 
                                                            contact != null ? contact.MobilePhone : string.Empty);
            }
        }

        /// <summary>
        /// 
        /// </summary>
        private void BindDataToControl()
        {
            if (CurrentAction == Enums.ActionForm.New)
            {
                currentPhieuBaoGia = new PhieuBaoGia() { PhieuBaoGiaChiTiets = new System.Data.Objects.DataClasses.EntityCollection<PhieuBaoGiaChiTiet>() };
            }
            txtPBGNote.Text = currentPhieuBaoGia.Note;
            txtPBGNumber.Text = currentPhieuBaoGia.Code;
            txtPBGTienCK.EditValue = currentPhieuBaoGia.TotalDiscountAmount;
            txtPBGTienTongCong.EditValue = currentPhieuBaoGia.TotalAmountBeforeVAT;
            txtPBGTienTruocVAT.EditValue = currentPhieuBaoGia.TotalAmount;
            txtPBGTienVAT.EditValue = currentPhieuBaoGia.TotalVATAmount;
            luePBGMasterLocation.EditValue = currentPhieuBaoGia.MasterLocation != null ? currentPhieuBaoGia.MasterLocation.ID : -1;
            luePBGVendor.EditValue = currentPhieuBaoGia.Vendor != null ? currentPhieuBaoGia.Vendor.ID : -1;
            grdPBGDetail.DataSource = null;
            grdPBGDetail.DataSource = currentPhieuBaoGia.PhieuBaoGiaChiTiets;
            
        }

        /// <summary>
        /// 
        /// </summary>
        private void BindControlToData()
        {
            currentPhieuBaoGia.Note = txtPBGNote.Text.Trim();
            currentPhieuBaoGia.Code = txtPBGNumber.Text.Trim();
            currentPhieuBaoGia.DocumentDate = Convert.ToDateTime(dtePBGDocumentDate.EditValue);
            currentPhieuBaoGia.TotalDiscountAmount = Convert.ToDecimal(txtPBGTienCK.EditValue);
            currentPhieuBaoGia.TotalAmountBeforeVAT = Convert.ToDecimal(txtPBGTienTruocVAT.EditValue);
            currentPhieuBaoGia.TotalAmount = Convert.ToDecimal(txtPBGTienTongCong.EditValue);
            //txtPBGTienTruocVAT.EditValue = currentPhieuBaoGia.TotalAmount - currentPhieuBaoGia.TotalDiscountAmount + currentPhieuBaoGia.TotalVATAmount;
            currentPhieuBaoGia.TotalVATAmount = Convert.ToDecimal(txtPBGTienVAT.EditValue);
            currentPhieuBaoGia.MasterLocation = luePBGMasterLocation.EditValue != null ? luePBGMasterLocation.Properties.GetDataSourceRowByKeyValue(luePBGMasterLocation.EditValue) as MasterLocation : null;
            currentPhieuBaoGia.Vendor = luePBGVendor.EditValue != null ? luePBGVendor.Properties.GetDataSourceRowByKeyValue(luePBGVendor.EditValue) as Vendor:null;
        }

        /// <summary>
        /// Tính giá tiền sau khi nhập đơn giá, VAT, chiết khấu của 1 dòng sản phẩm
        /// </summary>
        private void CalculateAmountForPhieuBaoGiaDetail(PhieuBaoGiaChiTiet pbgChiTiet)
        {
            pbgChiTiet.DiscountAmount = pbgChiTiet.UnitCost * pbgChiTiet.DiscountRate / 100;
            pbgChiTiet.VATAmount = (pbgChiTiet.UnitCost - pbgChiTiet.DiscountAmount) * pbgChiTiet.VATRate / 100;
            pbgChiTiet.Amount = pbgChiTiet.UnitCost - pbgChiTiet.DiscountAmount + pbgChiTiet.VATAmount;

        }

        /// <summary>
        /// Tính giá tiền sau khi nhập đơn giá, VAT, chiết khấu của toàn bộ phiếu báo giá
        /// </summary>
        private void CalculateAmountForPhieuBaoGia()
        {
            decimal totalAmount = 0;
            decimal totalAmountBeforeVAT = 0;
            decimal totalVATAmount = 0;
            decimal totalVATRate = 0;
            decimal totalDiscountAmount = 0;
            decimal totalDiscountRate = 0;
            foreach (PhieuBaoGiaChiTiet pbgChiTiet in currentPhieuBaoGia.PhieuBaoGiaChiTiets)
            {
                CalculateAmountForPhieuBaoGiaDetail(pbgChiTiet);
                totalAmount += pbgChiTiet.Amount.GetValueOrDefault();
                totalAmountBeforeVAT += pbgChiTiet.UnitCost.GetValueOrDefault();
                totalDiscountRate += pbgChiTiet.DiscountRate.GetValueOrDefault();
                totalDiscountAmount += pbgChiTiet.DiscountAmount.GetValueOrDefault();
                totalVATAmount += pbgChiTiet.VATAmount.GetValueOrDefault();
                totalVATRate += pbgChiTiet.VATRate.GetValueOrDefault();
            }
            txtPBGTienTruocVAT.EditValue = currentPhieuBaoGia.TotalAmountBeforeVAT = totalAmountBeforeVAT;
            txtPBGTienCK.EditValue = currentPhieuBaoGia.TotalDiscountAmount = totalDiscountAmount;
            currentPhieuBaoGia.TotalDiscountRate = totalDiscountRate;
            txtPBGTienVAT.EditValue = currentPhieuBaoGia.TotalVATAmount = totalVATAmount;
            currentPhieuBaoGia.TotalVATRate = totalVATRate;
            txtPBGTienTongCong.EditValue = currentPhieuBaoGia.TotalAmount = totalAmount;
        }

        /// <summary>
        /// Tất cả detail có cùng discount rate và VAT rate
        /// </summary>
        private void ApplyAllDiscountAndVAT(decimal discountRate, decimal vatRate)
        {
            foreach (PhieuBaoGiaChiTiet pbgChiTiet in currentPhieuBaoGia.PhieuBaoGiaChiTiets)
            {
                if (applyAllVAT)
                    pbgChiTiet.VATRate = vatRate;
                else if (applyAllDiscount)
                    pbgChiTiet.DiscountRate = discountRate;
            }

            CalculateAmountForPhieuBaoGia();

        }

        private void ResetAllData()
        {
            if (CurrentAction == Enums.ActionForm.New)
            {
                currentPhieuBaoGia = new PhieuBaoGia();
            }
            else if (CurrentAction == Enums.ActionForm.Edit)
            {
                if (currentPhieuBaoGia.PhieuBaoGiaChiTiets != null && currentPhieuBaoGia.PhieuBaoGiaChiTiets.Count > 0)
                {
                    List<PhieuBaoGiaChiTiet> lstChiTiet = currentPhieuBaoGia.PhieuBaoGiaChiTiets.ToList();
                    PhieuBaoGiaChiTiet pbgChiTiet;
                    for (int i = lstChiTiet.Count -1; i >=0; i--)
                    {
                        pbgChiTiet = lstChiTiet[i];
                        if (pbgChiTiet.EntityState == System.Data.EntityState.Added)
                            currentPhieuBaoGia.PhieuBaoGiaChiTiets.Remove(pbgChiTiet);    
                    }
                    
                }

                if (lstPhieuBaoGiaChiTietDeleted.Count > 0)
                {
                    foreach (PhieuBaoGiaChiTiet pbgDetail in lstPhieuBaoGiaChiTietDeleted)
                    {
                        pbgDetail.PhieuBaoGia = currentPhieuBaoGia;
                        currentPhieuBaoGia.PhieuBaoGiaChiTiets.Attach(pbgDetail);    
                    }                    
                    lstPhieuBaoGiaChiTietDeleted.Clear();
                }

                pharmacyContext.Reload(System.Data.Objects.RefreshMode.StoreWins, currentPhieuBaoGia);
                pharmacyContext.Reload(System.Data.Objects.RefreshMode.StoreWins, currentPhieuBaoGia.PhieuBaoGiaChiTiets);
            }
            BindDataToControl();
        }

        private bool ValidateData()
        {
            bool isValid = true;
            if (luePBGMasterLocation.EditValue == null || luePBGMasterLocation.Text.Trim().Length <= 0)
            {
                luePBGMasterLocation.ErrorText = string.Format(SR.Instance.GetString(Constant.KEY_EMPTYINFORMATION), SR.Instance.GetString(Constant.ENT_MASTERLOCATION));
                isValid = false;
            }
            //Reload Cửa Hàng
            else if (luePBGMasterLocation.EditValue != null)
            {
                MasterLocationRepository rMasterLocation = new MasterLocationRepository(pharmacyContext);
                int selectedMasterItemGroupID = (luePBGMasterLocation.Properties.GetDataSourceRowByKeyValue(luePBGMasterLocation.EditValue) as MasterLocation).ID;
                MasterLocation objTemp = rMasterLocation.AsQueryable().Where(m => m.ID == selectedMasterItemGroupID).First();
                if (objTemp == null)
                {
                    luePBGMasterLocation.ErrorText = string.Format(SR.Instance.GetString(Constant.KEY_OBJECTISDELETED), SR.Instance.GetString(Constant.ENT_MASTERLOCATION));
                    isValid = false;
                }
            }
            if (luePBGVendor.EditValue == null || luePBGVendor.Text.Trim().Length <= 0)
            {
                luePBGVendor.ErrorText = string.Format(SR.Instance.GetString(Constant.KEY_EMPTYINFORMATION), SR.Instance.GetString(Constant.ENT_VENDOR));
                isValid = false;
            }
            //Reload Nhà Cung Cấp
            else if (luePBGVendor.EditValue != null)
            {
                VendorRepository rVendor = new VendorRepository(pharmacyContext);
                int selectedMasterItemGroupID = (luePBGVendor.Properties.GetDataSourceRowByKeyValue(luePBGVendor.EditValue) as Vendor).ID;
                Vendor objTemp = rVendor.AsQueryable().Where(m => m.ID == selectedMasterItemGroupID).First();
                if (objTemp == null)
                {
                    luePBGVendor.ErrorText = string.Format(SR.Instance.GetString(Constant.KEY_OBJECTISDELETED), SR.Instance.GetString(Constant.ENT_VENDOR));
                    isValid = false;
                }
            }

            // Validate Đơn Giá của item
            List<PhieuBaoGiaChiTiet> lstPBGChiTiet = currentPhieuBaoGia.PhieuBaoGiaChiTiets.ToList();
            if (lstPBGChiTiet == null || lstPBGChiTiet.Count == 0)
            {
                mmeInformationDetail.Text = "Bạn chưa chọn sản phẩm để làm bảng báo giá.";                
                isValid = false;
            }
            else
            {
                int i =0;
                grvPBGDetail.ClearColumnErrors();
                foreach (PhieuBaoGiaChiTiet pbgChiTiet in lstPBGChiTiet)
                {
                    grvPBGDetail.FocusedRowHandle = i;
                    if (pbgChiTiet.MasterItem == null)
                    {                        
                        grvPBGDetail.SetColumnError(gcPBGDetailItem, "Chọn sản phẩm cho phiếu báo giá.");
                        isValid = false;
                    }
                    if (pbgChiTiet.UnitCost.GetValueOrDefault() == 0)
                    {
                        grvPBGDetail.SetColumnError(gcPBGPrice, "Nhập giá sản phẩm.");
                        isValid =false;
                    }
                    i++;
                }
            }

            return isValid;
        }
        #endregion

        #region Event Handlers
        private void grvPBGDetail_CustomDrawRowIndicator(object sender, DevExpress.XtraGrid.Views.Grid.RowIndicatorCustomDrawEventArgs e)
        {
            try
            {
                if (e.Info.IsRowIndicator)
                {
                    if (e.RowHandle != GridControl.NewItemRowHandle && e.RowHandle != GridControl.AutoFilterRowHandle)
                    {
                        if (e.RowHandle < 0)
                        {
                            e.Info.DisplayText = "";
                        }
                        else
                        {
                            e.Info.DisplayText = (e.RowHandle + 1).ToString();
                        }
                    }
                    if (e.RowHandle == GridControl.AutoFilterRowHandle)
                    {
                        e.Info.ImageIndex = -1;
                        e.Info.DisplayText = "Filter";
                    }
                }
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        private void FrmBangBaoGiaChiTiet_Load(object sender, EventArgs e)
        {
            try
            {
                SetDefaultValue();
                EnableControlToEdit();
                RegisterEventHandlers();
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        private void luePBGVendor_ButtonPressed(object sender, DevExpress.XtraEditors.Controls.ButtonPressedEventArgs e)
        {
            try
            {
                if (e.Button.Kind == DevExpress.XtraEditors.Controls.ButtonPredefines.OK) // Hiển thị thông tin chi tiết của object
                {
                    if (luePBGVendor.EditValue != null && luePBGVendor.Text != string.Empty)
                    {
                        Vendor currentObject = luePBGVendor.Properties.GetDataSourceRowByKeyValue(luePBGVendor.EditValue) as Vendor;
                        if (currentObject != null)
                        {
                            DisplayInformationOfObject(currentObject);
                        }
                    }
                }
                else if (e.Button.Kind == DevExpress.XtraEditors.Controls.ButtonPredefines.Ellipsis) // Hiển thị form quản lý và tạo mới object
                {
                    FrmVendor_List frm = new FrmVendor_List();
                    frm.RowSelected += frmVendor_RowSelected;
                    ViewManager.ShowView(frm);
                }
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        void frmVendor_RowSelected(object sender, Pharmacy.Ultilities.BaseEventArgs.RowSelectedArgs e)
        {
            try
            {
                LoadVendorList(e.CurrentSelectedRowID);
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        private void luePBGMasterLocation_ButtonPressed(object sender, DevExpress.XtraEditors.Controls.ButtonPressedEventArgs e)
        {
            try
            {
                if (e.Button.Kind == DevExpress.XtraEditors.Controls.ButtonPredefines.OK) // Hiển thị thông tin chi tiết của object
                {
                    if (luePBGMasterLocation.EditValue != null && luePBGMasterLocation.Text != string.Empty)
                    {
                        MasterLocation currentObject = luePBGMasterLocation.Properties.GetDataSourceRowByKeyValue(luePBGMasterLocation.EditValue) as MasterLocation;
                        if (currentObject != null)
                        {
                            DisplayInformationOfObject(currentObject);
                        }
                    }
                }
                else if (e.Button.Kind == DevExpress.XtraEditors.Controls.ButtonPredefines.Ellipsis) // Hiển thị form quản lý và tạo mới object
                {
                    FrmMasterLocation_List frm = new FrmMasterLocation_List();
                    frm.RowSelected += frmMasterLocation_RowSelected;
                    ViewManager.ShowView(frm);
                }
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        void frmMasterLocation_RowSelected(object sender, Pharmacy.Ultilities.BaseEventArgs.RowSelectedArgs e)
        {
            try
            {
                LoadMasterLocationList(e.CurrentSelectedRowID);
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        private void luePBGdetailItem_EditValueChanged(object sender, EventArgs e)
        {
            try
            {
                if ((sender as BaseEdit).EditValue != null)
                {
                    MasterItem item = luePBGdetailItem.GetDataSourceRowByKeyValue((sender as BaseEdit).EditValue) as MasterItem;
                    if (item != null)
                    {
                        PhieuBaoGiaChiTiet pbgDetail = grvPBGDetail.GetRow(grvPBGDetail.FocusedRowHandle) as PhieuBaoGiaChiTiet;
                        if (pbgDetail == null)
                        {
                            return;
                        }
                        if (grvPBGDetail.FocusedRowHandle < 0) // thêm mới
                        {
                            pbgDetail.UnitCost = 0;
                            pbgDetail.DiscountAmount = 0;
                            pbgDetail.DiscountRate = 0;
                            pbgDetail.VATRate = 0;
                            pbgDetail.VATAmount = 0;
                            pbgDetail.Amount = 0;
                        }
                        pbgDetail.MasterItem = item;
                        pbgDetail.UnitOfMeasure = item.UnitOfMeasure;
                    }
                }
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        private void luePBGdetailItem_ButtonPressed(object sender, DevExpress.XtraEditors.Controls.ButtonPressedEventArgs e)
        {
            try
            {
                if (e.Button.Kind == DevExpress.XtraEditors.Controls.ButtonPredefines.Ellipsis)
                {
                    FrmMasterItem_List frm = new FrmMasterItem_List();
                    frm.RowSelected += frmMasterItem_RowSelected;
                    ViewManager.ShowView(frm);
                }
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        void frmMasterItem_RowSelected(object sender, Pharmacy.Ultilities.BaseEventArgs.RowSelectedArgs e)
        {
            try
            {
                luePBGdetailItem.DataSource = LoadItemList(e.CurrentSelectedRowID);
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        private void btnDetailDelete_ButtonPressed(object sender, DevExpress.XtraEditors.Controls.ButtonPressedEventArgs e)
        {
            try
            {
                if (e.Button.Kind == DevExpress.XtraEditors.Controls.ButtonPredefines.Delete)
                {
                    PhieuBaoGiaChiTiet pbgDetail = grvPBGDetail.GetRow(grvPBGDetail.FocusedRowHandle) as PhieuBaoGiaChiTiet;
                    if (pbgDetail != null)
                    {
                        if(pbgDetail.EntityState != System.Data.EntityState.Added)
                            lstPhieuBaoGiaChiTietDeleted.Add(pbgDetail);
                        currentPhieuBaoGia.PhieuBaoGiaChiTiets.Remove(pbgDetail);
                        CalculateAmountForPhieuBaoGia();
                        grvPBGDetail.RefreshData();
                    }
                }
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        private void grvPBGDetail_ShownEditor(object sender, EventArgs e)
        {
            try
            {
                DevExpress.XtraGrid.Views.Grid.GridView view;
                view = sender as DevExpress.XtraGrid.Views.Grid.GridView;
                if (view.FocusedColumn.Name == gcPBGDetailItem.Name)
                {
                    LookUpEdit lue1 = (LookUpEdit)view.ActiveEditor;
                    List<int> arrMasterItemIDs = new List<int>();
                    arrMasterItemIDs.Add(-1);
                    if (currentPhieuBaoGia != null && currentPhieuBaoGia.PhieuBaoGiaChiTiets != null && currentPhieuBaoGia.PhieuBaoGiaChiTiets.Count > 0)
                    {
                        List<PhieuBaoGiaChiTiet> lstPhieuBaoGiaChiTiet = currentPhieuBaoGia.PhieuBaoGiaChiTiets.ToList();
                        for (int i = 0; i < lstPhieuBaoGiaChiTiet.Count; i++)
                        {
                            //if (i == gvSOLineItem.FocusedRowHandle) continue;
                            PhieuBaoGiaChiTiet pbgDetail = lstPhieuBaoGiaChiTiet[i];
                            if (pbgDetail != null && pbgDetail.MasterItem != null)
                                arrMasterItemIDs.Add(pbgDetail.MasterItem.ID);
                        }
                    }
                    lue1.Properties.DataSource = rMasterItem.AsQueryable()
                                                            .Where(item => !(arrMasterItemIDs.Contains(item.ID)))
                                                            .ToList();
                }
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        private void grvPBGDetail_CellValueChanged(object sender, DevExpress.XtraGrid.Views.Base.CellValueChangedEventArgs e)
        {
            try
            {
                PhieuBaoGiaChiTiet pbgChiTiet = grvPBGDetail.GetRow(grvPBGDetail.FocusedRowHandle) as PhieuBaoGiaChiTiet;
                if (pbgChiTiet != null)
                {
                    if (e.Column.FieldName == gcPBGPrice.FieldName)
                    {
                        pbgChiTiet.UnitCost = Convert.ToDecimal(e.Value);
                    }
                    if (e.Column.FieldName == gcPBGVAT.FieldName)
                    {
                        applyAllVAT = false;
                        pbgChiTiet.VATRate = Convert.ToDecimal(e.Value);
                    }
                    else if (e.Column.FieldName == gcPBGChietKhau.FieldName)
                    {
                        applyAllDiscount = false;
                        pbgChiTiet.DiscountRate = Convert.ToDecimal(e.Value);
                    }
                    if (grvPBGDetail.FocusedRowHandle < 0)
                    {
                        CalculateAmountForPhieuBaoGiaDetail(pbgChiTiet);
                        decimal totalAmountBeforeVAT = currentPhieuBaoGia.TotalAmountBeforeVAT.GetValueOrDefault() + pbgChiTiet.UnitCost.GetValueOrDefault();
                        decimal totalVATAmount = currentPhieuBaoGia.TotalVATAmount.GetValueOrDefault() + pbgChiTiet.VATAmount.GetValueOrDefault();
                        decimal totalDiscountAmount = currentPhieuBaoGia.TotalDiscountAmount.GetValueOrDefault() + pbgChiTiet.DiscountAmount.GetValueOrDefault();
                        decimal totalAmount = currentPhieuBaoGia.TotalAmount.GetValueOrDefault() + pbgChiTiet.Amount.GetValueOrDefault();
                        
                        txtPBGTienTruocVAT.EditValue = currentPhieuBaoGia.TotalAmountBeforeVAT = totalAmountBeforeVAT;
                        txtPBGTienCK.EditValue = currentPhieuBaoGia.TotalDiscountAmount = totalDiscountAmount;
                        //currentPhieuBaoGia.TotalDiscountRate = totalDiscountRate;
                        txtPBGTienVAT.EditValue = currentPhieuBaoGia.TotalVATAmount = totalVATAmount;
                        //currentPhieuBaoGia.TotalVATRate = totalVATRate;
                        txtPBGTienTongCong.EditValue = currentPhieuBaoGia.TotalAmount = totalAmount;
                    }
                    else
                    {
                        CalculateAmountForPhieuBaoGia();
                    }
                }

            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        private void txtPBGTienVAT_Click(object sender, EventArgs e)
        {
            txtPBGTienVAT.ShowPopup();
        }

        private void txtPBGTienCK_Click(object sender, EventArgs e)
        {
            txtPBGTienCK.ShowPopup();
        }

        private void txtPBGTienVAT_ButtonPressed(object sender, DevExpress.XtraEditors.Controls.ButtonPressedEventArgs e)
        {
            try
            {
                if (e.Button.Kind == DevExpress.XtraEditors.Controls.ButtonPredefines.Plus)
                {
                    applyAllVAT = true;
                    FrmCalculateDiscountAndVAT frm = new FrmCalculateDiscountAndVAT();
                    frm.VATAmount = currentPhieuBaoGia.TotalVATAmount.GetValueOrDefault();
                    frm.VATRate = currentPhieuBaoGia.TotalVATRate.GetValueOrDefault();
                    frm.DiscountAmount = currentPhieuBaoGia.TotalDiscountAmount.GetValueOrDefault();
                    frm.DiscountRate = currentPhieuBaoGia.TotalDiscountRate.GetValueOrDefault();
                    frm.TotalAmountBeforeVAT = currentPhieuBaoGia.TotalAmountBeforeVAT.GetValueOrDefault();
                    frm.TotalAmount = Convert.ToDecimal(currentPhieuBaoGia.TotalAmount.GetValueOrDefault());
                    frm.SubmittedForm += new FrmCalculateDiscountAndVAT.OnSubmittedForm(frmApplyDiscountAndVAT_SubmittedForm);
                    frm.ShowDialog();
                    applyAllVAT = false;
                }
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        private void txtPBGTienCK_ButtonPressed(object sender, DevExpress.XtraEditors.Controls.ButtonPressedEventArgs e)
        {
            try
            {
                if (e.Button.Kind == DevExpress.XtraEditors.Controls.ButtonPredefines.Plus)
                {
                    if (e.Button.Kind == DevExpress.XtraEditors.Controls.ButtonPredefines.Plus)
                    {
                        applyAllDiscount = true;
                        FrmCalculateDiscountAndVAT frm = new FrmCalculateDiscountAndVAT();
                        frm.VATAmount = currentPhieuBaoGia.TotalVATAmount.GetValueOrDefault();
                        frm.VATRate = currentPhieuBaoGia.TotalVATRate.GetValueOrDefault();
                        frm.DiscountAmount = currentPhieuBaoGia.TotalDiscountAmount.GetValueOrDefault();
                        frm.DiscountRate = currentPhieuBaoGia.TotalDiscountRate.GetValueOrDefault();
                        frm.TotalAmountBeforeVAT = currentPhieuBaoGia.TotalAmountBeforeVAT.GetValueOrDefault();
                        frm.TotalAmount = Convert.ToDecimal(currentPhieuBaoGia.TotalAmount.GetValueOrDefault());
                        frm.SubmittedForm += new FrmCalculateDiscountAndVAT.OnSubmittedForm(frmApplyDiscountAndVAT_SubmittedForm);
                        frm.ShowDialog();
                        applyAllDiscount = false;
                    }
                }
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        void frmApplyDiscountAndVAT_SubmittedForm(object sender, Core.CustomEventArgs.DiscountAndVATArgs e)
        {
            try
            {
                ApplyAllDiscountAndVAT(e.DiscountRate, e.VATRate);
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        private void btnNew_Click(object sender, EventArgs e)
        {
            try
            {
                CurrentAction = Enums.ActionForm.New;
                ResetAllData();
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            try
            {
                bool result = true;
                string message = string.Empty;
                if (ValidateData() && grvPBGDetail.HasColumnErrors == false)
                {
                    ViewManager.CreateWaitDialog();
                    ViewManager.SetWaitDialogCaption(SR.Instance.GetString(Constant.ENT_MASTERITEM), "Saving...");
                    BindControlToData();                    
                    if (CurrentAction == Enums.ActionForm.New)
                    {
                        pbgBO.CreateNewPhieuBaoGia(currentPhieuBaoGia);
                        CurrentAction = Enums.ActionForm.View;
                        ResetAllData();
                    }
                    if (CurrentAction == Enums.ActionForm.Edit)
                    {
                        result = pbgBO.EditPhieuBaoGia(currentPhieuBaoGia, lstPhieuBaoGiaChiTietDeleted, out message);
                        if (result == false)
                        {
                            MessageBox.Show(message);
                            return;
                        }
                        else
                            lstPhieuBaoGiaChiTietDeleted.Clear();
                    }
                }

            }
            catch (PessimisticLockingException ex)
            {
                LockingInfo lockInfo = ex.LockDataInfo.ToList()[0];
                MessageBox.Show(string.Format(SR.Instance.GetString(Constant.MSG_LOCKBYANOTHERUSER)
                                                , SR.Instance.GetString(Constant.ENT_PHIEUBAOGIA)
                                                , currentPhieuBaoGia.Code
                                                , lockInfo.UserName, lockInfo.ComputerName));
                ExceptionHandler.LogWriter.Write(ex, ExceptionHandler.LOG_CAT_GENERAL);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Có lỗi xảy ra. Vui lòng liên hệ Người quản trị hệ thống để được hỗ trợ.");
                ExceptionHandler.LogWriter.Write(ex, ExceptionHandler.LOG_CAT_GENERAL);
                this.Close();
            }
            finally
            {
                ViewManager.CloseWaitDialog();
            }            
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            try
            {
                ResetAllData();
            }
            catch (Exception ex)
            {

                MessageBox.Show("Có lỗi xảy ra. Vui lòng liên hệ Người quản trị hệ thống để được hỗ trợ.");
                ExceptionHandler.LogWriter.Write(ex, ExceptionHandler.LOG_CAT_GENERAL);
            }
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            try
            {
                bool result = true;
                string message = string.Empty;
                if (currentPhieuBaoGia != null && CurrentAction == Enums.ActionForm.Edit)
                {
                    if (MessageBox.Show(SR.Instance.GetString(Constant.MSG_CONFIRMDELETEOBJECT), "", MessageBoxButtons.YesNo) == System.Windows.Forms.DialogResult.Yes)
                    {
                        ViewManager.CreateWaitDialog();
                        ViewManager.SetWaitDialogCaption(SR.Instance.GetString(Constant.ENT_MASTERITEM), "Deleting...");
                        result = pbgBO.DeletePhieuBaoGia(currentPhieuBaoGia.ID, out message);
                        if (result == false)
                        {
                            MessageBox.Show(message);
                            return;
                        }
                        CurrentAction = Enums.ActionForm.New;
                        BindDataToControl();
                    }
                }
            }
            catch (PessimisticLockingException ex)
            {
                LockingInfo lockInfo = ex.LockDataInfo.ToList()[0];
                MessageBox.Show(string.Format(SR.Instance.GetString(Constant.MSG_LOCKBYANOTHERUSER)
                                                , SR.Instance.GetString(Constant.ENT_PHIEUBAOGIA)
                                                , currentPhieuBaoGia.Code
                                                , lockInfo.UserName, lockInfo.ComputerName));
                ExceptionHandler.LogWriter.Write(ex, ExceptionHandler.LOG_CAT_GENERAL);
            }
            catch (Exception ex)
            {
                MessageBox.Show("Có lỗi xảy ra. Vui lòng liên hệ Người quản trị hệ thống để được hỗ trợ.");
                ExceptionHandler.LogWriter.Write(ex, ExceptionHandler.LOG_CAT_GENERAL);
                this.Close();
            }
            finally
            {
                ViewManager.CloseWaitDialog();
            }
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void txtPBGTienCK_EditValueChanged(object sender, EventArgs e)
        {
            try
            {
                
                decimal discountAmount = Convert.ToDecimal(txtPBGTienCK.EditValue);
                if (currentPhieuBaoGia.TotalAmountBeforeVAT.GetValueOrDefault() > 0)
                {
                    decimal discountRate = (discountAmount / currentPhieuBaoGia.TotalAmountBeforeVAT.GetValueOrDefault()) * 100;
                    ApplyAllDiscountAndVAT(discountRate, 0);
                    applyAllDiscount = false;
                }
               
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }

        private void txtPBGTienVAT_EditValueChanged(object sender, EventArgs e)
        {
            try
            {
                decimal VATAmount = Convert.ToDecimal(txtPBGTienVAT.EditValue);
                decimal discountAmount = Convert.ToDecimal(txtPBGTienCK.EditValue);
                if (currentPhieuBaoGia.TotalAmountBeforeVAT.GetValueOrDefault() - discountAmount > 0)
                {
                    decimal VATRate = (VATAmount / (currentPhieuBaoGia.TotalAmountBeforeVAT.GetValueOrDefault() - discountAmount)) * 100;
                    ApplyAllDiscountAndVAT(0, VATRate);
                    applyAllVAT = false;
                }
            }
            catch (Exception ex)
            {

                ExceptionHandler.LogWriter.Write(ex.Message, ExceptionHandler.LOG_CAT_GENERAL);
                MessageBox.Show(ex.Message);
            }
        }
        #endregion        

        private void txtPBGTienCK_KeyPress(object sender, KeyPressEventArgs e)
        {
            applyAllDiscount = true;
            applyAllVAT = false;
        }

        private void txtPBGTienVAT_KeyPress(object sender, KeyPressEventArgs e)
        {
            applyAllDiscount = false;
            applyAllVAT = true;
            
        }
    }
}